package com.sky.besthardtool.category.usb.base;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.util.Log;

import com.sky.besthardtool.base.ActionBarBaseA;
import com.sky.besthardtool.utils.ByteUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by Administrator on 2018/3/9.
 */

public class BaseA extends ActionBarBaseA {
    private static final String TAG = "USB_HOST_BASE";

    public static final String ACTION_USB_PERMISSION = "cn.sky.d149.USB";
    private PendingIntent mPermissionIntent;
    private BroadcastReceiver mUsbPermissionActionReceiver;
    public UsbManager mUsbManager;
    public UsbDevice mUsbDevice;
    public UsbInterface mInterface;
    public UsbDeviceConnection mDeviceConnection;

    private static final int VendorID = 1046;    //这里要改成自己的硬件ID
    private static final int ProductID = 53;


    public UsbEndpoint epOut;
    public UsbEndpoint epIn;


    public byte[] inStream = new byte[64]; //大小可修改
    public byte[] outStream = new byte[64]; //大小可修改
    public List<Byte> effectData = new ArrayList<>(); //有效数据
    public byte[] cutData; //截取的需要输出的数据

    public int ret = 0;//发送接收状态: >0 发送接收成功,<0发送接收失败 ,0表示发送空字节

    public byte[] cmd;

    public boolean isControlTrans = true; //判断是否是控制传输


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
/*      检测USB设备插入和拔出
        IntentFilter usbDeviceStateFilter = new IntentFilter();
        usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        registerReceiver(mUsbReceiver, usbDeviceStateFilter);
        */

        mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
        //注册USB设备权限管理广播
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        registerReceiver(mUsbPermissionActionReceiver, filter);


        // 获取UsbManager
        mUsbManager = (UsbManager) getSystemService(USB_SERVICE);

        enumerateDevice();

        findInterface();

        openDevice();

        assignEndpoint();


    }

    /**
     * 分配端点，IN | OUT，即输入输出；此处我直接用1为OUT端点，0为IN，当然你也可以通过判断
     */
    //USB_ENDPOINT_XFER_BULK
     /*
     #define USB_ENDPOINT_XFER_CONTROL 0 --控制传输
     #define USB_ENDPOINT_XFER_ISOC 1 --等时传输(实时)
     #define USB_ENDPOINT_XFER_BULK 2 --块传输(批量)
     #define USB_ENDPOINT_XFER_INT 3 --中断传输
     * */
    private void assignEndpoint() {

        if (mInterface != null) { //这一句不加的话 很容易报错  导致很多人在各大论坛问:为什么报错呀

            //这里的代码替换了一下 按自己硬件属性判断吧

            for (int i = 0; i < mInterface.getEndpointCount(); i++) {

                UsbEndpoint ep = mInterface.getEndpoint(i);

                if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_INT) {
                    isControlTrans = false; //中断传输
                    if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
                        epOut = ep;
                    } else {
                        epIn = ep;
                    }
                }
            }
        }

        Log.d(TAG, "端点分配完成");
    }

    /**
     * 打开设备
     */
    private void openDevice() {
        if (mInterface != null) {
            UsbDeviceConnection conn = null;
            // 在open前判断是否有连接权限；对于连接权限可以静态分配，也可以动态分配权限，可以查阅相关资料
            if (mUsbManager.hasPermission(mUsbDevice)) {
                Log.d(TAG, "有usb权限");
                conn = mUsbManager.openDevice(mUsbDevice);
            } else {
                Log.d(TAG, "无usb权限");
                getUsbPermission();
            }

            if (conn == null) {
                return;
//                Toast.makeText(this, "未连接USB", Toast.LENGTH_SHORT).show();
//                finish();
            }

            if (conn.claimInterface(mInterface, true)) {
                mDeviceConnection = conn; // 到此你的android设备已经连上HID设备
                Log.d(TAG, "打开设备成功");
                String mySerial = mDeviceConnection.getSerial();
                Log.d(TAG, "设备串口号为:" + mySerial);
            } else {
                conn.close();
            }
        }
    }

    /**
     * 获取usb设备传输数据权限
     */
    private void getUsbPermission() {

        mUsbPermissionActionReceiver = new BroadcastReceiver() {
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (ACTION_USB_PERMISSION.equals(action)) {
                    context.unregisterReceiver(this);//解注册
                    synchronized (this) {
                        UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                        if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                            if (null != usbDevice) {
                                Log.e(TAG, usbDevice.getDeviceName() + "已获取USB权限");

                                UsbDeviceConnection conn = mUsbManager.openDevice(mUsbDevice);

                                if (conn == null) {
                                    return;
                                }

                                if (conn.claimInterface(mInterface, true)) {
                                    mDeviceConnection = conn; // 到此你的android设备已经连上HID设备
                                    Log.d(TAG, "打开设备成功");
                                    String mySerial = mDeviceConnection.getSerial();
                                    Log.d(TAG, "设备串口号为:" + mySerial);
                                } else {
                                    conn.close();
                                }
                            }
                        } else {
                            //user choose NO for your previously popup window asking for grant perssion for this usb device
                            Log.e(TAG, String.valueOf("USB权限已被拒绝,Permission denied for device" + usbDevice));
                        }
                    }

                }
            }
        };


        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);

        if (mUsbPermissionActionReceiver != null) {
            registerReceiver(mUsbPermissionActionReceiver, filter);
        }

        mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);

        boolean has_idCard_usb = false;
        for (final UsbDevice usbDevice : mUsbManager.getDeviceList().values()) {

            if (usbDevice.getProductId() == 53)//身份证设备USB
            {
                has_idCard_usb = true;
                Log.e(TAG, usbDevice.getDeviceName() + "已找到身份证USB");
                if (mUsbManager.hasPermission(usbDevice)) {
                    Log.e(TAG, usbDevice.getDeviceName() + "已获取过USB权限");
                } else {
                    Log.e(TAG, usbDevice.getDeviceName() + "请求获取USB权限");
                    mUsbManager.requestPermission(usbDevice, mPermissionIntent);
                }
            }

        }

        if (!has_idCard_usb) {
            Log.e(TAG, "未找到身份证USB");
        }

    }

    /**
     * 找设备接口
     */
    private void findInterface() {
        if (mUsbDevice != null) {
            Log.d(TAG, "interfaceCounts : " + mUsbDevice.getInterfaceCount());
            UsbInterface intf = mUsbDevice.getInterface(1);
            mInterface = intf;
            Log.d(TAG, "找到我的设备接口");
//            for (int i = 0; i < myUsbDevice.getInterfaceCount(); i++) {
//                UsbInterface intf = myUsbDevice.getInterface(i);
//                // 根据手上的设备做一些判断，其实这些信息都可以在枚举到设备时打印出来
//                if (intf.getInterfaceClass() == 8
//                        && intf.getInterfaceSubclass() == 6
//                        && intf.getInterfaceProtocol() == 80) {
//                    myInterface = intf;
//                    Log.d(TAG, "找到我的设备接口");
//                }
//                break;
//            }
        }
    }

    /**
     * 枚举设备
     */
    private void enumerateDevice() {
        if (mUsbManager == null)
            return;

        HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
        if (!deviceList.isEmpty()) { // deviceList不为空
            StringBuffer sb = new StringBuffer();
            for (UsbDevice device : deviceList.values()) {
                sb.append(device.toString());
                sb.append("\n");
//                info.setText(sb);
                // 输出设备信息
                Log.d(TAG, "DeviceInfo: " + device.getVendorId() + " , "
                        + device.getProductId());

                // 枚举到设备
                if (device.getVendorId() == VendorID
                        && device.getProductId() == ProductID) {
                    mUsbDevice = device;
                    Log.d(TAG, "枚举设备成功");
                }
            }
        }
    }


    BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                Log.e(TAG, "拔出usb了");
                UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if (device != null) {
                    Log.e(TAG, "设备的ProductId值为：" + device.getProductId());
                    Log.e(TAG, "设备的VendorId值为：" + device.getVendorId());
                }
            } else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
                Log.e(TAG, "新插入一个设备");
            }
        }
    };


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mUsbPermissionActionReceiver != null) {
            unregisterReceiver(mUsbPermissionActionReceiver);
        }

    }

    /**
     * 获取有效数据
     * <p>
     * 分为两个步骤:
     * 接收完整的包
     * 获取包中的有效数据
     * 去掉头尾
     * 包括起始符,终止符,校验位,数据长度等
     *
     * @return
     */
    public byte[] cutEffectData() {

        //获取完整包
        while (true) {
            ret = mDeviceConnection.bulkTransfer(epIn, inStream, inStream.length, 2000);
            if (ret > -1) {
                Log.d(TAG, "接受" + (ret > 0 ? "succeed" : "fail") + "--" + ByteUtil.byteArrayToString(inStream));

                for (int i = 0; i < inStream.length; i++) {
                    effectData.add(inStream[i]);
                }
            } else {
                break;
            }
        }

        //获取有效数据
        int size = effectData.size();
        System.out.println("**********数据长度" + size);
        for (int i = 0; i < size; i++) {
            if (effectData.get(i) == 0xA9 && effectData.get(5) + 8 == effectData.size()) {

                for (int j = i + 1; j < size; j++) {
                    effectData.remove(i + 1);
                }
                break;
            }
        }

        byte[] r = new byte[effectData.get(5) - 1];

        for (int i = 0; i < effectData.get(5) - 1; i++) {
            r[i] = effectData.get(7 + i);
        }

        effectData.clear();

        return r;
    }


    public byte[] buildCmd(byte[] prefix, String body) {
        int l = prefix.length;
        byte[] b = ByteUtil.HexToByteArr(body);
        int bl = b.length;
        byte[] c = new byte[l + bl + 2];


        for (int i = 0; i < l; i++) {
            c[i] = prefix[i];
        }

        for (int i = 0; i < bl; i++) {
            c[i + l] = b[i];
        }

        c[l + bl] = ByteUtil.getXor(c, 1);


        c[l + bl + 1] = (byte) 0xa9;
        return c;
    }
}
